﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using YQBlog.Models;
using System.Web.Mvc;
using System.Configuration;
using res = Resource.Models.Web.Web;
using System.Text.RegularExpressions;
using System.IO;
using Common;
using System.Web.Helpers;
using System.Web.Security;
using System.Net.Mail;
using System.Text;
using System.Net;
using System.Web.UI;

namespace YQBlog.General
{
    public class WebUtils
    {
        /// <summary>
        /// 网站配置信息
        /// </summary>
        public static GeneralConfigInfo configinfo = GeneralConfigs.GetConfig();

        /// <summary>
        /// 分类链接url
        /// </summary>
        public static string GetCateUrl(CategoryModel category)
        {
            return GetCurrentLangPath()+ (!string.IsNullOrWhiteSpace(category.ReName) ? "/"+category.ReName + "/" : "/cate/" + category.CateId);
        }

        /// <summary>
        /// 分类链接url
        /// </summary>
        public static string GetCateUrl(string rename, string id)
        {
            return GetCurrentLangPath() + (!string.IsNullOrWhiteSpace(rename) ? "/" + rename + "/" : "/cate/" + id); 
        }

        /// <summary>
        /// 文章链接url
        /// </summary>
        public static string GetArticleUrl(int id, string reName)
        {
            return !string.IsNullOrWhiteSpace(reName) ? "/article/" + reName : "/archive/" + id.ToString();
        }

        /// <summary>
        /// 文章链接url
        /// </summary>
        public static string GetArticleUrl(blog_varticle varticle)
        {
            return !string.IsNullOrWhiteSpace(varticle.rename) ? "/article/" + varticle.rename : "/archive/" + varticle.id.ToString();
        }

        /// <summary>
        /// 获得对应视图名称
        /// </summary>
        public static string GetViewName(string customView,string defaultView)
        {
            return string.IsNullOrWhiteSpace(customView) ? defaultView : customView;
        }

        /// <summary>
        /// 获得配置文件路径
        /// </summary>
        public static string GetWebConfigPath()
        {
            return ConfigurationManager.AppSettings["BlogConfig"].ToString();
        }

        /// <summary>
        /// 获得当前语言下分类语言文件名
        /// </summary>
        public static string GetCategoryLangName()
        {
            string cateName = "Category.Lang.js";
            string weblang = Resource.Models.Web.Web.Lang != "" ? "." + Resource.Models.Web.Web.Lang : "";
            if (weblang != "")
                cateName = cateName.Replace(".js", weblang + ".js");
            return cateName;
        }

        /// <summary>
        /// 视图切换，记录session,cookie(用于缓存定制)以及更新视图引擎路径
        /// </summary>
        public static void ChangeTheme(string key)
        {
            string theme=string.IsNullOrEmpty(key) ? "" : key;

            HttpCookie themeCookie = new HttpCookie("web");
            themeCookie["theme"] = theme;
            themeCookie.Expires = DateTime.Now.AddDays(7d);
            HttpContext.Current.Response.Cookies.Add(themeCookie);

            DataCache.SetCache("DecorateCount", CurrentDecorateCount(theme), DateTime.Now.AddMinutes(180.0), TimeSpan.Zero);
             
            ViewEngines.Engines.Clear();
            ViewEngines.Engines.Add(new BlogViewEngine(theme));
        }

        /// <summary>
        /// 当前语言路径
        /// </summary>
        public static string GetCurrentLangPath()
        {
            return res.Lang != configinfo.DefaultLang ? "/" + res.Lang : "";
        }

        /// <summary>
        /// 当前风格
        /// </summary>
        public static string GetCurrentTheme()
        {
            return HttpContext.Current.Request.Cookies["web"]["theme"] != null ? MyString(HttpContext.Current.Request.Cookies["web"]["theme"].ToString()) : YQBlog.General.WebUtils.configinfo.Theme;
        }

        /// <summary>
        /// 获得页面类型下拉列表
        /// </summary>
        public static List<PageType> GetTypeList()
        {
            List<PageType> items = new List<PageType>();
            items.Add(new PageType
            {
                TypeName = Resource.Views.Admin.Admin.Article,
                TypeId = 1
            });
            items.Add(new PageType
            {
                TypeName = Resource.Views.Admin.Admin.SinglePage,
                TypeId = 2
            });
            items.Add(new PageType
            {
                TypeName = Resource.Views.Admin.Admin.Album,
                TypeId = 4
            });
            items.Add(new PageType
            {
                TypeName = Resource.Views.Admin.Admin.Message,
                TypeId = 6
            });
            items.Add(new PageType
            {
                TypeName = Resource.Views.Admin.Admin.CustomArea,
                TypeId = 7
            });
            items.Add(new PageType
            {
                TypeName = Resource.Views.Admin.Admin.CustomGlobalArea,
                TypeId = 8
            });
            return items;
        }

        /// <summary>
        /// 获得站点语言下拉列表
        /// </summary>
        public static List<PageLang> GetLangList()
        {
            List<PageLang> items = new List<PageLang>();
            items.Add(new PageLang
            {
                Key="中(简体)",
                Value = "zh-cn"
            });
            items.Add(new PageLang
            {
                Key = "中(繁体)",
                Value = "zh-tw"
            });
            items.Add(new PageLang
            {
                Key = "English",
                Value = "en-us"
            });
            return items;
        }

        public static readonly string[] Langs = new[] { "/en-us", "/zh-tw", "/zh-cn" };

        public static readonly string[] UrlPrefix = new[] { "", "archive", "archive", "", "album","","" };

        /// <summary>
        /// 获得性别下拉列表
        /// </summary>
        public static List<SelectItem> GetGenderList()
        {
            List<SelectItem> items = new List<SelectItem>();
            items.Add(new SelectItem
            {
                Key = res.Secrecy,
                Value = "0"
            });
            items.Add(new SelectItem
            {
                Key=res.Male,
                Value = "1"
            });
            items.Add(new SelectItem
            {
                Key = res.Female,
                Value = "2"
            });
            return items;
        }

        /// <summary>
        /// ubb转html
        /// </summary>
        /// <param name="argString"></param>
        /// <returns></returns>
        public static string ubb2html(string argString)
        {
            string tString = argString;
            if (tString != "")
            {
                Regex tRegex;
                bool tState = true;
                tString = tString.Replace("&", "&amp;");
                tString = tString.Replace(">", "&gt;");
                tString = tString.Replace("<", "&lt;");
                tString = tString.Replace("\"", "&quot;");
                tString = tString.Replace("&amp;#91;", "&#91;");
                tString = tString.Replace("&amp;#93;", "&#93;");
                tString = tString.Replace("\r\n", "<br/>");
                tString = Regex.Replace(tString, @"\[br\]", "<br/>", RegexOptions.IgnoreCase);
                string[,] tRegexAry = {
                  {@"\[p\]([^\[]*?)\[\/p\]", "$1<br/>"},
                  {@"\[b\]([^\[]*?)\[\/b\]", "<b>$1</b>"},
                  {@"\[i\]([^\[]*?)\[\/i\]", "<i>$1</i>"},
                  {@"\[u\]([^\[]*?)\[\/u\]", "<u>$1</u>"},
                  {@"\[ol\]([^\[]*?)\[\/ol\]", "<ol>$1</ol>"},
                  {@"\[ul\]([^\[]*?)\[\/ul\]", "<ul>$1</ul>"},
                  {@"\[li\]([^\[]*?)\[\/li\]", "<li>$1</li>"},
                  {@"\[code\]([^\[]*?)\[\/code\]", "<div class=\"ubb_code\">$1</div>"},
                  {@"\[quote\]([^\[]*?)\[\/quote\]", "<fieldset class=\"comment_quote\"><legend> "+Resource.Views.Home.Home.Quote+" </legend>$1</fieldset>"},
                  {@"\[color=([^\]]*)\]([^\[]*?)\[\/color\]", "<font style=\"color: $1\">$2</font>"},
                  {@"\[hilitecolor=([^\]]*)\]([^\[]*?)\[\/hilitecolor\]", "<font style=\"background-color: $1\">$2</font>"},
                  {@"\[align=([^\]]*)\]([^\[]*?)\[\/align\]", "<div style=\"text-align: $1\">$2</div>"},
                  {@"\[url=js:([^\]]*)\]([^\[]*?)\[\/url\]", "<a href=\"###\" onclick=\"$1\">$2</a>"},
                  {@"\[url=([^\]]*)\]([^\[]*?)\[\/url\]", "<a href=\"$1\">$2</a>"},
                  {@"\[code=([^\]]*)\](.*?)\[\/code\]", "<pre class=\"brush:$1\">$2</pre>"},
                  {@"\[img\]([^\[]*?)\[\/img\]", "<img src=\"$1\" />"}
                };
                while (tState)
                {
                    tState = false;
                    for (int ti = 0; ti < tRegexAry.GetLength(0); ti++)
                    {
                        tRegex = new Regex(tRegexAry[ti, 0], RegexOptions.IgnoreCase);
                        if (tRegex.Match(tString).Success)
                        {
                            tState = true;
                            tString = Regex.Replace(tString, tRegexAry[ti, 0], tRegexAry[ti, 1], RegexOptions.IgnoreCase);
                        }
                    }
                }
            }
            return GetCode(tString);
        }

        /// <summary>
        /// 代码引用处理
        /// </summary>
        public static string GetCode(string str)
        {
            Regex re = new Regex(@"<pre.*?</pre>", RegexOptions.Multiline);
            string tmp = "";
            var a = re.Matches(str);
            foreach (Match m in a)
            {
                if (m.Success)
                {
                    tmp = m.Value.Replace("<br/>", "\r\n");
                    str = str.Replace(m.Value, tmp);
                }
            }
            return str;
        }

        /// <summary>
        /// html转ubb
        /// </summary>
        public static string HtmlToUBB(string _Html)
        {
            _Html = Regex.Replace(_Html, "<br[^>]*>", "\n");
            _Html = Regex.Replace(_Html, @"<p[^>\/]*\/>", "\n");
            _Html = Regex.Replace(_Html, "<hr[^>]*>", "[hr]");
            _Html = Regex.Replace(_Html, "<(\\/)?blockquote([^>]*)>", "[$1blockquote]");
            _Html = Regex.Replace(_Html, "<img[^>]*smile=\"(\\d+)\"[^>]*>", "‘[s:$1]");
            _Html = Regex.Replace(_Html, "<img[^>]*src=[\'\"\\s]*([^\\s\'\"]+)[^>]*>", "[img]$1[/img]");
            _Html = Regex.Replace(_Html, "<a[^>]*href=[\'\"\\s]*([^\\s\'\"]*)[^>]*>(.+?)<\\/a>", "[url=$1]$2[/url]");
            _Html = Regex.Replace(_Html, "<b>(.+?)</b>", @"\[b\]$1\[/b\]");
            _Html = Regex.Replace(_Html, "<[^>]*?>", "");
            _Html = Regex.Replace(_Html, "&amp;", "&");
            _Html = Regex.Replace(_Html, "&nbsp;", " ");
            _Html = Regex.Replace(_Html, "&lt;", "<");
            _Html = Regex.Replace(_Html, "&gt;", ">");
            return _Html;
        }

        /// <summary>
        /// 获得插图总数
        /// </summary>
        /// <returns></returns>
        public static int GetDecorateCount(string theme)
        {

            string cacheKey = "DecorateCount";
            object cache = DataCache.GetCache(cacheKey);
            if (cache == null)
            {
                try
                {
                    cache = CurrentDecorateCount(theme);
                    if (cache != null)
                    {
                        DataCache.SetCache(cacheKey, cache, DateTime.Now.AddMinutes(180.0), TimeSpan.Zero);
                    }
                }
                catch (Exception) { }
            }
            return Utils.ObjectToInt(cache);
        }

        /// <summary>
        /// 当前风格下插图总数
        /// </summary>
        /// <returns></returns>
        private static int CurrentDecorateCount(string theme)
        {
            try
            {
                string decoratepath = theme == "" ? "/Content/image/decorate" : "/Themes/" + theme + "/Content/image/decorate";
                return Directory.GetFiles(System.Web.HttpContext.Current.Server.MapPath(decoratepath), "*.jpg").Length - 1;
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 从文本中提取用户集合
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static List<string> GetUsersFromTxt(string str)
        {
            List<string> lst = new List<string>();
            Regex regstr = new Regex(@"@(.*?)\s", RegexOptions.IgnoreCase);
            MatchCollection mc = regstr.Matches(str);
            foreach (Match match in mc)
            {
                lst.Add(match.Groups[1].Value);
            }
            lst = lst.GroupBy(x => x).Select(x => x.Key).ToList();

            return lst;
        }

        /// <summary>
        /// WebMail邮件发送
        /// </summary>
        public static void SendWebMail(string emailTo, string emailTitle, string emailContent,string[] filePath = null, string[] additionalHeaders = null)        
        {
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");  
            WebMail.SmtpServer = configinfo.SmtpServer;//获取或设置要用于发送电子邮件的 SMTP 中继邮件服务器的名称。            
            WebMail.SmtpPort = configinfo.SmtpPort;//发送端口                    
            WebMail.UserName = configinfo.SmtpUser;//账号名            
            WebMail.From = configinfo.AdminEmail;//邮箱名            
            WebMail.Password = configinfo.SmtpPass;//密码   
            WebMail.EnableSsl = true;//是否启用 SSL GMAIL 需要 而其他都不需要 具体看你在邮箱中的配置    
            WebMail.SmtpUseDefaultCredentials = true;//是否使用默认配置                    
            try
            {
                if (reg.IsMatch(emailTo))
                {
                    WebMail.Send(to: emailTo, subject: emailTitle, body: emailContent, isBodyHtml: true, filesToAttach: filePath, additionalHeaders: additionalHeaders);
                }
            }
            catch{}        
        }

        /// <summary>
        /// WebMail邮件发送
        /// </summary>
        public static void SendWebMail(string emailTo, string emailTitle, string emailContent)
        {
            SendWebMail(emailTo,  emailTitle,  emailContent);
        }

        /// <summary>
        /// 发送电子邮件
        /// </summary>
        public static void SendSysMail(string to, string subject, string body)
        {
            string from = configinfo.AdminEmail;
            string host = configinfo.SmtpServer;
            string userName = configinfo.SmtpUser;
            string password = configinfo.SmtpPass;
            int port = configinfo.SmtpPort;
            if (!string.IsNullOrEmpty(from) && !string.IsNullOrEmpty(host) && !string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
                SendMail(from, to, subject, body, host, port, userName, password);
        }

        /// <summary>
        /// 发送电子邮件
        /// </summary>
        /// <param name="from">发件人</param>
        /// <param name="to">收件人</param>
        /// <param name="subject">邮件主题</param>
        /// <param name="body">邮件内容</param>
        /// <param name="host">发送服务地址(smtp.gmail.com)</param>
        /// <param name="port">发送邮件服务器端口</param>
        /// <param name="userName">用户名</param>
        /// <param name="password">密码</param>
        public static void SendMail(string from, string to, string subject, string body, string host, int port, string userName, string password)
        {
            MailMessage message = new MailMessage(from, to, subject, body);
            message.IsBodyHtml = true;
            message.BodyEncoding = Encoding.UTF8;
            SmtpClient client = new SmtpClient(host);
            client.Credentials = new NetworkCredential(userName, password);
            client.DeliveryMethod = SmtpDeliveryMethod.Network;
            client.EnableSsl = true;
            client.Port = port;
            client.Send(message);
        }

        /// <summary>
        /// 生成静态页
        /// </summary>
        public static void CreateHtml(int typeid,int id, string rename, DateTime d)
        {
            foreach (string lang in configinfo.WebLangList)
            {
                CreateHtml(typeid,id, rename, lang, d);
            }
        }

        /// <summary>
        /// 生成静态页(单个语言)
        /// </summary>
        public static void CreateHtml(int typeid, int id, string rename, string lang, DateTime d)
        {
            if (typeid != 1)
                return;
            Page page = new Page();
            string folder = "~/" + GetStaticFolder(d, lang).Trim('/') + "/";
            string folderPath = page.Server.MapPath(folder);
            Utils.CreateFolder(folderPath);
            string langStr = configinfo.DefaultLang == lang ? "/" : "/" + lang + "/";
            string sourcePath = configinfo.Weburl.Trim('/') + langStr + UrlPrefix[typeid] + "/" + id.ToString();
            string aimPath = folderPath + id.ToString() + ".html";
            if (rename.Length > 0)
            { aimPath = folderPath + rename + ".html"; }
            Utils.CreateHtml(sourcePath, aimPath);
        }

        /// <summary>
        /// 删除静态页
        /// </summary>
        public static void DeleteHtml(int id, string rename,DateTime d)
        {
            foreach (string lang in configinfo.WebLangList)
            {
                Page page = new Page();
                string folder = "~/" + GetStaticFolder(d, lang).Trim('/') + "/";
                string aimPath = page.Server.MapPath(folder);
                if (rename.Length > 0)
                { aimPath += rename + ".html"; }
                else
                { aimPath += id.ToString() + ".html"; }

                Utils.DeleteHtml(aimPath);
            }
        }
        
        /// <summary>
        /// 静态文件生成目录
        /// </summary>
        public static string GetStaticFolder(DateTime date,string lang)
        {
            string langstr = (lang == configinfo.DefaultLang ? "" : lang);
            string path = configinfo.WebStaticFolder;
            string year = date.Year.ToString();
            string month = date.Month < 10 ? "0" + date.Month.ToString() : date.Month.ToString();
            string day = date.Day.ToString();
            return path.Replace("{lang}", langstr).Replace("{year}", year).Replace("{month}", month).Replace("{day}", day).Replace("//", "/");
        }


        /// <summary>
        /// 网站文章url,根据相关设置及当前环境数据确定正确的文章url
        /// </summary>
        public static string GetYQUrl(blog_varticle varticle)
        {
            int pageId = varticle.parentid > 0 ? varticle.parentid : varticle.id;
            string url = "";
            if (configinfo.IfWebStatic == 1 && GetCurrentTheme()== MyString(configinfo.Theme))
            {
                url = "/" + WebUtils.GetStaticFolder(varticle.createdate, res.Lang).Trim('/') + "/";
                if (varticle.rename.Length > 0)
                { url += varticle.rename + ".html"; }
                else
                { url += pageId.ToString() + ".html"; }
            }
            else
            {
                url = GetYQUrl(varticle.url, 1);
            }
            return url;
        }

        /// <summary>
        /// 网站文章url
        /// </summary>
        public static string GetYQUrl(blog_article article)
        {
            string url = "";
            string articleurl = article.rename.Trim().Length > 0 ? article.rename.Trim() : article.id.ToString();
            if (article.typeid == 1)
            {
                if (configinfo.IfWebStatic == 1 && GetCurrentTheme() == MyString(configinfo.DefaultLang))
                {
                    url = "/" + WebUtils.GetStaticFolder(article.createdate, res.Lang).Trim('/') + "/" + articleurl + ".html";
                }
                else
                {
                    url = GetYQUrl(articleurl, 1);
                }
            }
            else
            {
                url = GetYQUrl(articleurl, article.typeid);
            }
            return url;
        }

        /// <summary>
        /// 字符串为空或者null时处理
        /// </summary>
        public static string MyString(string str, string def = "")
        {
            return string.IsNullOrWhiteSpace(str) ? def : str;
        }

        /// <summary>
        /// 返回“多少xxx前”时间
        /// </summary>
        public static string DateFromNow(DateTime dt, int days = 10)
        {
            TimeSpan span = DateTime.Now - dt;
            if (span.TotalDays > days)
            {
                return dt.ToShortDateString();
            }
            else
            {
                if (span.TotalDays > 1)
                {
                    return string.Format("{0} " + res.DaysAgo, (int)Math.Floor(span.TotalDays));
                }
                else if (span.TotalHours > 1)
                {
                    return string.Format("{0} " + res.HoursAgo, (int)Math.Floor(span.TotalHours));
                }
                else if (span.TotalMinutes > 1)
                {
                    return string.Format("{0} " + res.MinutesAgo, (int)Math.Floor(span.TotalMinutes));
                }
                else if (span.TotalSeconds >= 1)
                {
                    return string.Format("{0} " + res.SecAgo, (int)Math.Floor(span.TotalSeconds));
                }
                else { return "1 " + res.SecAgo; }
            }
        }

        /// <summary>
        /// 网站页面url
        /// </summary>
        public static string GetYQUrl(string url, int typeid = 0)
        {
            return GetCurrentLangPath() + (typeid > 0 ? "/" + WebUtils.UrlPrefix[typeid] + "/" : "") + url;
        }

        /// <summary>
        /// 用户提交数据处理 datatype:1--ubb,2--html
        /// </summary>
        public static string FileterData(string content, int datatype)
        {
            if (datatype == 2)
            {
                return Utils.FileterScript(content);
            }
            else
            {
                return WebUtils.ubb2html(content);
            }
        }
    }

    /// <summary>
    /// 异步分页
    /// </summary>
    public class AjaxPager
    {
        private int pagesize = 4;
        private int currentpage = 1;
        private int maxpage = 1;
        private int prevPage;
        private int nextPage;

        public AjaxPager(int p_size, int p_currentpage, int p_maxpage)
        {
            this.pagesize = p_size;
            this.currentpage = p_currentpage;
            this.maxpage = p_maxpage;
            setPrevPage();
            setNextPage();
        }

        public void setPrevPage()
        {
            if (currentpage > 1)
                prevPage = currentpage - 1;
            else
                prevPage = currentpage;
        }

        public void setNextPage()
        {
            if (currentpage < maxpage)
                nextPage = currentpage + 1;
            else
                nextPage = currentpage;
        }

        public string getPageInfoHtml()
        {
            if (maxpage < 2)
                return "";
            string btnPrevPage = "<a href='javascript:;' p=" + prevPage + ">" + res.Preview + "</a>&nbsp;";
            string btnNextPage = "&nbsp;<a href='javascript:;' p=" + nextPage + ">" + res.Next + "</a>";
            if (currentpage == 1)
            {
                btnPrevPage = "";
            }
            if (currentpage == maxpage)
            {
                btnNextPage = "";
            }
            string pageNumberList = "";
            if (maxpage > 2 * pagesize + 3)
            {
                pageNumberList = pageNumberList += getNumberPage(1);
                int start = 2;
                int end = maxpage - 1;
                int added = 0;

                if ((currentpage - pagesize) <= 2)
                {
                    added = 2 - (currentpage - pagesize);
                    end = currentpage + pagesize + added;
                }
                else if ((currentpage + pagesize) >= (maxpage - 1))
                {
                    added = (currentpage + pagesize) - (maxpage - 1);
                    start = currentpage - pagesize - added;
                }
                else
                {
                    start = currentpage - pagesize;
                    end = currentpage + pagesize;
                }

                if (start > 2)
                { pageNumberList = pageNumberList + "... "; }

                for (int i = start; i <= end; i++)
                {
                    pageNumberList += getNumberPage(i);
                }

                if (end < (maxpage - 1))
                { pageNumberList = pageNumberList + "... "; }

                pageNumberList += getNumberPage(maxpage);
            }
            else
            {
                for (int i = 1; i <= maxpage; i++)
                {
                    pageNumberList += getNumberPage(i);
                }
            }

            string html = btnPrevPage + pageNumberList + btnNextPage;
            return html;
        }

        public string getNumberPage(int p_pageno)
        {
            string t = "";
            string p = p_pageno.ToString();
            if (p_pageno == currentpage)
            { t = "<b style='color:red'>" + p + "</b>&nbsp;"; }
            else
            {
                t = "<a  href='javascript:;' p=" + p_pageno + ">" + p + "</a>&nbsp;";
            }
            return t;
        }
    }
}